import xbmc
import xbmcgui
import xbmcaddon
import urllib
import urllib2
import re
import os
import time
import cgi
import sys
import httplib
import urlparse
import gzip

# Global settings
__settings__ = xbmcaddon.Addon("script.mytvandme")
#__apiurl__ 		= 'localhost'
__apiurl__ 	= 'www.mytvand.me'
__apipath__ 	= '/upload'

# Database info
DB_FFILE = xbmc.translatePath('special://home/userdata/Database/MyVideos75.db')
GZ_FFILE = xbmc.translatePath('special://home/userdata/Database/MyTVandMeDatabase.db.gz')

# Debugging info
print "[ADDON] " + __settings__.getAddonInfo("id") + " version " + __settings__.getAddonInfo("version")

# Send a notice.  Specify message and duration.
def sendNotice(msg,force):
	if (__settings__.getSetting( "notifications" ) == 'true' or force == 1):
		xbmc.executebuiltin('Notification(MyTVand.Me,' + msg + ',4000,' + __settings__.getAddonInfo("icon") + ')')

def debug(message):	
	if (__settings__.getSetting( "debug" ) == 'true'):
		message = "MyTVand.Me: " + message
		print message

# The following function is modified from the snippet at:
# http://code.activestate.com/recipes/146306/
def encode_multipart_formdata(fields, files=()):
	"""
	fields is a dictionary of name to value for regular form fields.
	files is a sequence of (name, filename, value) elements for data to be
	uploaded as files.
	Return (content_type, body) ready for httplib.HTTP instance
	"""
	BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
	CRLF = '\r\n'
	L = []
	for key, value in fields.items():
		L.append('--' + BOUNDARY)
		L.append('Content-Disposition: form-data; name="%s"' % key)
		L.append('')
		L.append(value)
	for (key, filename, value) in files:
		L.append('--' + BOUNDARY)
		L.append('Content-Disposition: form-data; name="%s"; filename="%s"' %
				 (key, filename))
		content_type = 'application/octet-stream'
		L.append('Content-Type: %s' % content_type)
		L.append('')
		L.append(value)
	L.append('--' + BOUNDARY + '--')
	L.append('')
	body = CRLF.join(L)
	content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
	return content_type, body

def post_multipart(host, selector, fields, files):
	content_type, body = encode_multipart_formdata(fields, files)
	#h = httplib.HTTPConnection(host, 1822)
	h = httplib.HTTPConnection(host)
	headers = {
		'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/A.B (KHTML, like Gecko) Chrome/X.Y.Z.W Safari/A.B.',
		'Content-Type': content_type
		}
	code = '404'
	h.request('POST', selector, body, headers)
	res = h.getresponse()
	code = res.read()
	h.close()
	return code

def sendReq(username, password):
	debug("Opening Database File.")
	f_in = open(DB_FFILE, 'rb')
	f_out = gzip.open(GZ_FFILE, 'wb')
	debug("Zipping database file.")
	f_out.writelines(f_in)
	f_out.close()
	f_in.close()
	values = {'username':username,'password':password}
	files = [('upfile', "MyTVandMeDatabase.db.gz", open(GZ_FFILE, 'rb').read())]
	debug("Uploading Database")
	maxtries = 3
	tries = 1
	data = ""
	while(tries <= maxtries):
		try:
			data = ""
			data=post_multipart(__apiurl__,__apipath__, values, files)
			tries = maxtries + 1
		except Exception, e:
			data = "404"
			tries += 1
			debug('Error uploading attempt no. ' + str(tries) + '; ' + str(e))
	
	return data
  
def sendUpdate():
	username = __settings__.getSetting( "username" )
	password = __settings__.getSetting( "password" )
	if (username == '' or password == ''):
		sendNotice("Configure your account details before submitting.", 1)
		return
		
	code = sendReq(username, password)
	debug(code)

	if code == '117':
		sendNotice("Update sent successfully", 0)
	elif code == '1040':
		sendNotice("Invalid Username/Password", 1)
	elif code == '500':
		sendNotice("No File Uploaded", 0)
	elif code == '404':
		sendNotice("HTTP Error", 0)
	elif code == '666':
		sendNotice("File System Error", 0)
	else: sendNotice("Unspecified Error", 0)
      
def getModDate():
	return os.stat(DB_FFILE).st_mtime

def waiter(seconds):
	debug('waiting ' + str(seconds) + ' secs')
	waitsecs = 0
	while (not xbmc.abortRequested and waitsecs < seconds):
		time.sleep(1)
		waitsecs += 1
			
# Main execution path
oldModDate = getModDate()
updateDelay = 60
uname = __settings__.getSetting( "username" )
passwd = __settings__.getSetting( "password" )

if uname == '' or passwd == '':
	sendNotice("Please enter your username and password.", 1)
	
debug('Waiting to send updates')
while (not xbmc.abortRequested):
	try:
		intervalDelay = int(__settings__.getSetting( "interval" ))
		if intervalDelay < 300:
			intervalDelay = 300
	except:
		intervalDelay = 300
	
	debug('Checking for library updates')	
	newModDate = getModDate()
	debug("saved timestamp   " + str(oldModDate))
	debug("current timestamp " + str(newModDate))
	
	if oldModDate == newModDate:
		debug('No change in Timestamp')
	else:
		while (oldModDate != newModDate):
			debug('Change in timestamp, sleep to let update finish')
			waiter(updateDelay)
			oldModDate = newModDate
			newModDate = getModDate()
		
		debug('timestamp stopped changing, sending update now')
		oldModDate = newModDate
		sendUpdate()
		
	waiter(intervalDelay)	